/*
    Copyright © 2010  Ahti Legonkov
    
    This file is part of j+-.
    
    j+- is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    j+- is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package cx.ath.skyflyer.javapm.visitor;

import japa.parser.ast.body.MethodDeclaration;
import japa.parser.ast.body.VariableDeclarator;
import japa.parser.ast.body.VariableDeclaratorId;
import japa.parser.ast.expr.NameExpr;
import japa.parser.ast.expr.VariableDeclarationExpr;
import japa.parser.ast.stmt.BlockStmt;
import japa.parser.ast.visitor.VoidVisitorAdapter;
import java.util.LinkedList;

/**
 * @author Ahti Legonkov
 */
public class FindLocalVariableVisitor extends VoidVisitorAdapter {

    private final NameExpr varName;
    private boolean isLocalVariable = false;
    private VariableDeclarationExpr localVariable;
    private boolean finishSearch = false;
    private final LinkedList<BlockStmt> pathToUsage = new LinkedList();

    public boolean isLocalVariable() {
        return isLocalVariable;
    }

    public VariableDeclarationExpr localVariable() {
        return localVariable;
    }
    
    public FindLocalVariableVisitor(NameExpr varName) {
        this.varName = varName;
    }

    @Override
    public void visit(MethodDeclaration n, Object arg) {
        super.visit(n, arg);
    }

    @Override
    public void visit(BlockStmt n, Object arg) {
        if (finishSearch)
            return;

        final boolean prevIsLocalVariable = isLocalVariable;
        super.visit(n, arg);
        if (!finishSearch)
            isLocalVariable = prevIsLocalVariable;
    }

    @Override
    public void visit(VariableDeclarator n, Object arg) {
        super.visit(n, arg);
    }

    @Override
    public void visit(VariableDeclarationExpr n, Object arg) {
        for (VariableDeclarator v : n.getVars()) {
            v.accept(this, arg);
        }
        if (isLocalVariable)
            localVariable = n;
    }

    @Override
    public void visit(VariableDeclaratorId n, Object arg) {
        if (n.getName().equals(varName.getName()))
            isLocalVariable = true;
    }

    @Override
    public void visit(NameExpr n, Object arg) {
        // if the search hits the name expression that we are trying to determine
        // whether it's a local varialbe or not, then it means that we haven't
        // found that local variable yet.
        if (n == varName) {
            finishSearch = true;
            return;
        }
    }
}
